<!DOCTYPE html>
<!-- 现在即使开启怪异模式，也会按照标准模式来（版本比较新，怪异模式也只能兼容之前的若干版本），但是 document.compatMode 还是能区分 -->
<!-- 混杂模式是为兼容之前的浏览器 -->
<!-- 怪异模式也是分版本的，ie6的怪异模式（兼容ie6之前的浏览器，ie6之前都不按标准的），以及谷歌的怪异模式 -->
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>

        #img-wrapper {
            position: absolute;
            top: 1500px;
            width: 400px;
            height: 400px;
            border: 1px solid #0099ff;
        }
        img {
            width: 100%;
            height: 100%;
        }
        body {
            height: 3000px;
        }

    </style>
</head>
<body>
    <p>
        <label for="demo">username:</label>
        <input type="text" id='demo'>
        <!-- 点label，input也可以聚焦 为input绑定事件，点label也能触发  -->
    </p>

    <input type="text" value='aaa' id='demo2' data="duyi">

    <div id = "img-wrapper"></div>



    <ul id="wrapper">

    </ul>



    <div class="wrapper" id='ow'>
        <p class='    demo   active   box    '>
            <span class='   active   '>1</span>
            <span class='demo  box'>2</span>
        </p>
        <p class='demo'>
            <span class='   demo    active'>3</span>
        </p>
    </div>
    <script>

        //一. 要说 DOCTYPE 渲染模式，其和最后页面被展示的效果有关系，那我们深入浅出一下吧

        // 浏览器请求页面大致经历了哪些过程：
        // 1. 发送url，DNS查询，请求IP地址（页面所在服务器地址）
        // 2. TCP三次握手
        // 3. 服务器响应内容，html css js img 等
        // 4. 按照成哥讲的js时间线理解js解析执行的过程就好
        // 5. 渲染引擎渲染页面： DOM树 CSSDOM树，生成RENDER树，布局，渲染
        // 6. TCP四次挥手

        // 这里着重说一下渲染页面这部分，有渲染引擎主要参与
        // 这一过程有很多部分参与，说一下浏览器的组成，和组成部分的功能。（ppt）
        // 网络：用于通讯，传输的部分
        // 数据存储： 拥有提供缓存的功能的部分

        // 细化一下来说其渲染的过程：.... 

        // 在布局这块 是由不同渲染模式来定义不同的规则的
        // 拿一个举例子  IE6怪异模式盒子模型 和 标准模式盒子模型    IE6怪异模式和标准模式的margin: 100 auto 0;
        // 总结一下: 渲染的最后效果，由于采取模式的不同而产生了不同的效果
        // 我们能大概了解了渲染模式是什么意思有什么样的作用。

        // IE6怪异模式其实现在主流浏览器都已经不兼容了（不去迎合了，被废弃掉了）但我们可以了解一下历史以及上述的过程。
        // 为什么要有怪异模式和标准模式的区别->向前兼容
        // 如何控制显示页面的浏览器采取什么样的模式来渲染  DOCTYPE




        // 二.

        // Label 标签

        // var oLabel = document.getElementsByTagName('label')[0];
        // oLabel.onclick = function () {
        //     console.log(this);
        //     // 点击label也会触发input绑定的点击事件
        //     // 先触发自身绑定的
        // }
        // var oInput = document.getElementById('demo');  
        // oInput.onclick = function () {
        //     console.log(this);
        // }
    




        // 属性 特性
        // 特性（可以通称为属性）天生就可以具有的如 id type class value checked  
        // 特性是有映射关系的 dom对象---html标签 一一对应，直接通过dom.id dom.className等读写，有的特性（value）通过js增加后也不会出现在行间上，但是已经有了
        // 属性包含特性  非特性的属性 data cst log times等等  
        // 无映射关系（行间的就是行间的） js对象---html标签, console.log(input.data) 返回undefined，赋值会赋到dom对象，但是不会修改行间的属性
        // var input = document.getElementById('demo2');
        
        // setAttribute getAttribute 
        // 可以读写任何属性到行间，只能操作行间的，设置的非特性的属性不会映射到dom对象







        // 图片预加载 有充裕的能力时可以这么做
        // 加载图片一点点出现，用户体验比较差

        // var oImage = new Image();
        // var oImage = document.createElement('img');
        // // console.log(oImage);
        // // 图片元素创建有专门的构造函数，这两种创建方法其实一样的
        // oImage.onload = function () {
        //     var div = document.getElementById('img-wrapper');
        //     div.appendChild(this);
        // }
        // oImage.src = './微信图片_20200519110522.jpg';

        




        // 图片懒加载， BOM中说了
        // 淘宝 图片预加载+懒加载
        // 监控滑轮事件   不断判断当前div的位置
        // 采取预加载模式
        // 把图片正式的添加到页面之中

        // HTMLDivElement.prototype.checkSelf = function () {
        //     var that = this;
        //     if (!this.lock) { // 加一个锁防止重复设置定时器
        //         if(this.offsetTop < window.innerHeight + window.pageYOffset) {
        //             console.log('start')
        //             this.lock = true;
        //             setTimeout(function () {
        //                 var oImage = new Image(); // img元素可以通过构造函数来创建
        //                 oImage.onload = function () {
        //                     that.appendChild(this);
        //                 }
        //                 oImage.src = 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2187922730,604631233&fm=27&gp=0.jpg';

        //             }, 100);
        //         }
        //     }
        // }

        // window.onscroll = function () {
        //     var wrapper = document.getElementById('img-wrapper');
        //     wrapper.checkSelf();
        // }

        




        // Math 是一个对象，并不是构造函数，原型直接继承Object.prototype，但又好像是Math构造函数创建的
        // Math.random() [0, 1)

        //  12-36之间的随机数     36-12=24   24 * Math.random() -> [0, 24)  再加 12    12 + 24 * Math.random() -> [12, 36)

        // var n = Math.random() * 100;
        // if (n <= 1) {
        //     console.log('one')
        // }else if (n <= 10) {
        //     console.log('two');
        // }else if (n < 50) {
        //     console.log('three');
        // }else {
        //     console.log('thank you')
        // }






        // 文档碎片，实际上并没有提升效率
        // var oF = document.createDocumentFragment();  // 创建文档碎片节点
        // console.log(oF, [oF]);
        // var ul = document.getElementById('wrapper');
        // for(var i = 0; i < 10; i ++){
        //     var newLi = document.createElement('li');
        //     newLi.innerHTML = i + '';
        //     oF.appendChild(newLi);
        //     // ul.appendChild(newLi);
        // }        
        // ul.appendChild(oF);

        // 文档碎片本意是 集中操作来减少布局计算（重排）和绘制次数（重绘）,但是现实很骨感
        // 其实可以采用字符串（利用模板字符串）拼接的方式，这种方式更节省效率(这种方式一定了解)
        // var str = "";
        // var ul = document.getElementById('wrapper');
        // for(var i = 0; i < 10; i ++){
        //     str += '<li>' + i + '</li>';
        // }
        // ul.innerHTML = str;
        // 操作DOM成本高，所以可以采用虚拟DOM来搞定
        // 虚拟DOM简单原理






        // 封装getElementsByClassName()
        Element.prototype.getElementsByClassName = Document.prototype.getElementsByClassName = function(_className) {
            // 获取document下面的所有标签，或者元素下面的所有标签
            var allDomArray = [].slice.call(this.getElementsByTagName('*'), 0);
            // 通过slice方法截取类数组，最后返回一个数组
            var newDomArray = [];
            function trimClassName (dom) {
                var reg = /\s+/g;
                // 把所有的空格变成一个先
                var newClassStr = dom.className.replace(reg, ' ');
                return newClassStr;
            }

            allDomArray.forEach(function (ele, index) {
                // console.log(ele, index);
                var newClassStr = trimClassName(ele).trim();
                var classNameArray = newClassStr.split(' ');
                classNameArray.forEach(function (className, index) {
                    // 对于数组中的每个元素执行该函数
                    // forEach不如for循环来的快（每次调用回调函数都会创建执行期上下文，压入执行栈中，会消耗性能），而且不能跳出循环
                    if (className == _className) {
                        newDomArray.push(ele);
                    }
                })
            });
            return newDomArray;
        }

        // console.log(document.getElementsByClassName('demo'));
        // var ow = document.getElementById('ow');
        // console.log(ow.getElementsByClassName('demo'));




        // // 断点调试
        // // 是调试的一种方式，平时直接使用console的报错信息以及console.log输出在控制台配合调试

        // var ow = document.getElementById('o');
        // debugger  // 这是一个断点
        // // 程序运行到断点处，会停止
        // // 方便查看变量在哪一步的值是不是符合预期
        // // 可以在控制台的source处手动打断点
        // ow.style.backgroundColor = 'red';

    </script>

</body>
</html>